//+------------------------------------------------------------------+
//|                                              GoldenTradingEA.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

// 输入参数
input string   EAComment = "王者无敌";           // EA注释
input bool     DynamicSwitch = false;           // 动态开关 (原: DongTaiKaiGuan)
input int      VolatilityFactor = 59;           // 波动率因子 (原: BoDongLu)
input int      AdaptiveFactor = 68;             // 自适应因子 (原: ZiShiYing)
input int      EntryFactor = 10;                // 开仓因子 (原: KaiCangYinZi)
input int      ExitFactor = 15;                 // 平仓因子 (原: PingCangYinZi)
input int      ExitFactor2 = 31;                // 二次平仓因子 (原: PingCangYinZi2)
input int      SpeedFactor = 9;                 // 速度因子 (原: SuDuYinZi)
input int      ProfitFactor = 15;               // 盈利因子 (原: YingLiYinZi)
input double   FixedLot = 0.1;                  // 固定仓位 (原: Lots)
input bool     CompoundSwitch = false;          // 复利开关 (原: FuliKaiGuan)
input int      RiskPercent = 10;                // 风险百分比 (原: Risk)
input string   AsianSessionSettings = "";       // 亚洲盘设置
input bool     EarlySession = false;            // 早盘开关 (原: ZaoPan)
input int      StartHour = 1;                   // 开始时间 (原: Tima)
input int      EndHour = 19;                    // 结束时间 (原: Timb)
input int      StopLossPoints = 114;            // 止损点数 (原: StopLos)

// 全局变量
int       g_totalOrders = 0;           // 总订单数 (原: by_in_1)
int       g_pendingOrders = 0;         // 挂单数量 (原: by_in_2)
int       g_magicNumber = 19828668;    // EA魔术数字 (原: by_in_3)
int       g_slippage = 3;              // 滑点设置 (原: by_in_5)
bool      g_isTradeAllowed = true;     // 是否允许交易 (原: by_bo_6)
double    g_buyVolume = 0;             // 买入仓位 (原: by_do_7)
double    g_sellVolume = 0;            // 卖出仓位 (原: by_do_8)
double    g_buyProfit = 0;             // 买入盈利 (原: by_do_9)
double    g_sellProfit = 0;            // 卖出盈利 (原: by_do_10)
int       g_pointMultiplier = 10;      // 点数乘数 (原: by_in_11)
int       g_buyCount = 0;              // 买入订单数 (原: by_in_12)
int       g_sellCount = 0;             // 卖出订单数 (原: by_in_13)
double    g_pointValue = 0;            // 点值 (原: by_do_14)
double    g_currentPrice = 0;          // 当前价格 (原: by_do_15)
double    g_highPrice = 0;             // 最高价 (原: by_do_16)
int       g_tradeMode = 0;             // 交易模式 (原: by_in_17)
double    g_stopLoss = 0;              // 止损价格 (原: by_do_18)
double    g_takeProfit = 0;            // 止盈价格 (原: by_do_19)
double    g_buyOpenPrice = 0;          // 买入开仓价 (原: by_do_20)
int       g_buyTicket = 0;             // 买入订单号 (原: by_in_21)
int       g_sellTicket = 0;            // 卖出订单号 (原: by_in_22)
double    g_buyStopLoss = 0;           // 买入止损价 (原: by_do_23)
double    g_sellStopLoss = 0;          // 卖出止损价 (原: by_do_24)
double    g_buyTakeProfit = 0;         // 买入止盈价 (原: by_do_25)
double    g_sellTakeProfit = 0;        // 卖出止盈价 (原: by_do_26)
double    g_buyProfitTotal = 0;        // 买入总盈利 (原: by_do_27)
double    g_sellProfitTotal = 0;       // 卖出总盈利 (原: by_do_28)
double    g_buyVolumeTotal = 0;        // 买入总仓位 (原: by_do_29)
double    g_sellVolumeTotal = 0;       // 卖出总仓位 (原: by_do_30)
double    g_buyLastVolume = 0;         // 买入最后仓位 (原: by_do_31)
double    g_sellLastVolume = 0;        // 卖出最后仓位 (原: by_do_32)
double    g_buyLastProfit = 0;         // 买入最后盈利 (原: by_do_33)
double    g_sellLastProfit = 0;        // 卖出最后盈利 (原: by_do_34)
double    g_buyOpenPriceTotal = 0;     // 买入总开仓价 (原: by_do_35)
double    g_sellOpenPriceTotal = 0;    // 卖出总开仓价 (原: by_do_36)
datetime  g_buyLastTime = 0;           // 买入最后时间 (原: by_lo_37)
datetime  g_sellLastTime = 0;          // 卖出最后时间 (原: by_lo_38)
datetime  g_lastBarTime = 0;           // 最后K线时间 (原: by_lo_39)
datetime  g_currentBarTime = 0;        // 当前K线时间 (原: by_lo_40)
datetime  g_buyTime = 0;               // 买入时间 (原: by_lo_41)
datetime  g_sellTime = 0;              // 卖出时间 (原: by_lo_42)
int       g_lastMarkedBarTime = 0;     // 最后标记K线时间 (原: by_lo_43)
string    g_comment;                   // EA注释 (原: by_st_44)
int       g_errorCode = 0;             // 错误代码 (原: by_in_45)
int       g_retryCount = 1;            // 重试次数 (原: by_in_46)
string    g_symbol;                    // 交易品种 (原: by_st_47)
datetime  g_expiryDate = D'2027.03.02';// EA过期时间 (原: by_lo_49)
bool      g_isSpreadOK = true;         // 点差是否正常 (原: by_bo_51)
bool      g_isTrendOK = true;          // 趋势是否正常 (原: by_bo_52)
datetime  g_timeOfLastMarkedBar = 0;   // 最后标记K线时间 (原: timeOfLastMarkedBar)
datetime  g_lastBarTime2 = 0;          // 备用最后K线时间 (原: dfz_lo_8)

//+------------------------------------------------------------------+
//| EA初始化函数                                                     |
//+------------------------------------------------------------------+
int OnInit()
{
    // 初始化时间变量
    g_timeOfLastMarkedBar = iTime(_Symbol, PERIOD_CURRENT, 1);
    g_lastBarTime2 = g_timeOfLastMarkedBar;
    g_lastBarTime = g_timeOfLastMarkedBar;
    g_currentBarTime = g_timeOfLastMarkedBar;
    
    // 根据时间周期设置g_lastMarkedBarTime - 完全匹配MT4代码
    if(Period() == PERIOD_M15)
    {
        g_lastMarkedBarTime = 910;
    }
    else if(Period() == PERIOD_M30)
    {
        g_lastMarkedBarTime = 1810;
    }
    else if(Period() == PERIOD_H1)
    {
        g_lastMarkedBarTime = 3610;
    }
    else if(Period() == PERIOD_H4)
    {
        g_lastMarkedBarTime = 14410;
    }
    
    // 设置点值
    g_pointValue = MathPow(0.1, _Digits);
    
    // 根据小数位数设置点数乘数
    if(_Digits == 5 || _Digits == 3)
    {
        g_pointMultiplier = 10;
    }
    
    // 黄金特殊处理
    if(StringFind(_Symbol, "XAU", 0) >= 0 || StringFind(_Symbol, "GOLD", 0) >= 0)
    {
        if(_Digits == 2) g_pointMultiplier = 10;
        if(_Digits == 3) g_pointMultiplier = 100;
        if(_Digits == 4) g_pointMultiplier = 1000;
    }
    
    // 获取交易参数
    g_tradeMode = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE);
    
    // 设置时间间隔限制
    if(Period() == PERIOD_M15)
    {
        g_lastBarTime = 910;
    }
    else if(Period() == PERIOD_M30)
    {
        g_lastBarTime = 1810;
    }
    else if(Period() == PERIOD_H1)
    {
        g_lastBarTime = 3610;
    }
    else if(Period() == PERIOD_H4)
    {
        g_lastBarTime = 14410;
    }
    
    // 设置图表属性 - 完全匹配MT4代码
    ChartSetInteger(0, CHART_SHOW_ASK_LINE, true);  // 对应MT4的ChartSetInteger(0,40,1)
    
    // 创建EURUSD按钮 - 完全匹配MT4代码
    ObjectCreate(0, "EURUSD", OBJ_BUTTON, 0, 0, 0);
    ObjectSetInteger(0, "EURUSD", OBJPROP_XDISTANCE, 15);  // 对应MT4的15
    ObjectSetInteger(0, "EURUSD", OBJPROP_YDISTANCE, 15);  // 对应MT4的15
    ObjectSetInteger(0, "EURUSD", OBJPROP_XSIZE, 330);     // 对应MT4的330
    ObjectSetInteger(0, "EURUSD", OBJPROP_YSIZE, 245);     // 对应MT4的245
    ObjectSetString(0, "EURUSD", OBJPROP_FONT, "Arial");   // 对应MT4的dfz_st_3
    ObjectSetInteger(0, "EURUSD", OBJPROP_FONTSIZE, 9);    // 对应MT4的dfz_in_4
    ObjectSetInteger(0, "EURUSD", OBJPROP_COLOR, clrLightSlateGray);  // 对应MT4的LightSlateGray
    ObjectSetInteger(0, "EURUSD", OBJPROP_BGCOLOR, clrDimGray);       // 对应MT4的DimGray
    ObjectSetInteger(0, "EURUSD", OBJPROP_BORDER_COLOR, clrDimGray);  // 对应MT4的DimGray
    ObjectSetInteger(0, "EURUSD", OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, "EURUSD", OBJPROP_STATE, false);
    ObjectSetInteger(0, "EURUSD", OBJPROP_HIDDEN, true);
    ObjectSetInteger(0, "EURUSD", OBJPROP_SELECTABLE, false);
    ObjectSetInteger(0, "EURUSD", OBJPROP_SELECTED, false);
    ObjectSetInteger(0, "EURUSD", OBJPROP_READONLY, true);
    ObjectSetInteger(0, "EURUSD", OBJPROP_ZORDER, 0);
    
    // 创建图表对象
    CreateChartObjects();
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EA反初始化函数                                                   |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // 删除所有对象 - 完全匹配MT4代码
    ObjectsDeleteAll(0, 23);
}

//+------------------------------------------------------------------+
//| EA主循环函数                                                     |
//+------------------------------------------------------------------+
void OnTick()
{
    // 检查是否允许交易
    if(!IsTradeAllowed())
    {
        ShowMessage("请启用自动交易", true);
        return;
    }
    
    // 获取当前点差
    g_currentPrice = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * _Point;
    g_isSpreadOK = true;
    
    // 检查点差
    if(IsTesting())
    {
        if((g_currentPrice > g_pointMultiplier * 2.5 && StringFind(_Symbol, "GBPUSD", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 3.5 && StringFind(_Symbol, "XAUUSD", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 3.5 && StringFind(_Symbol, "GOLD", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 2 && StringFind(_Symbol, "USDJPY", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 4 && StringFind(_Symbol, "GBPCAD", 0) >= 0))
        {
            ShowMessage("您回测点差过大，请照ECN平台点差设置", true);
            g_isSpreadOK = false;
            return;
        }
    }
    else
    {
        if((g_currentPrice > g_pointMultiplier * 2.6 && StringFind(_Symbol, "GBPUSD", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 3.7 && StringFind(_Symbol, "XAUUSD", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 3.7 && StringFind(_Symbol, "GOLD", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 2.3 && StringFind(_Symbol, "USDJPY", 0) >= 0) ||
           (g_currentPrice > g_pointMultiplier * 5 && StringFind(_Symbol, "GBPCAD", 0) >= 0))
        {
            ShowMessage("点差过高: " + DoubleToString(g_currentPrice, 2), true);
            g_isTrendOK = false;
            return;
        }
        else
        {
            g_isTrendOK = true;
        }
    }
    
    // 获取市场数据
    MqlRates rates[];
    ArraySetAsSeries(rates, true);
    CopyRates(_Symbol, PERIOD_CURRENT, 0, 3, rates);
    
    // 计算趋势强度
    double trendStrength = CalculateTrendStrength(rates[0].high, rates[0].close, rates[0].open, rates[0].low);
    
    // 更新订单统计
    CountOrders();
    
    // 获取高低点
    g_highPrice = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, PRICE_HIGH, AdaptiveFactor, 2));
    double lowPrice = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, PRICE_LOW, AdaptiveFactor, 2));
    double speedHigh = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, PRICE_HIGH, SpeedFactor, 2));
    double speedLow = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, PRICE_LOW, SpeedFactor, 2));
    
    // 更新K线时间
    g_lastBarTime2 = iTime(_Symbol, PERIOD_CURRENT, 1);
    g_lastBarTime = g_lastBarTime2;
    g_currentBarTime = g_lastBarTime2;
    
    // 检查趋势强度
    if(trendStrength == 100)
    {
        g_isSpreadOK = false;
        g_isTrendOK = false;
    }
    else
    {
        g_isTrendOK = true;
    }
    
    // GBPCAD交易逻辑
    if(StringFind(_Symbol, "GBPCAD", 0) != 0)
    {
        // 买入条件
        if(CheckBuyCondition(g_isSpreadOK, g_buyCount, rates[0].close, lowPrice, VolatilityFactor, g_pointMultiplier, g_pointValue, trendStrength,
                             EntryFactor, rates[0].close, speedLow, TimeCurrent(), g_buyCount, g_buyCount, g_buyCount, g_buyCount, g_expiryDate) &&
           g_lastBarTime != g_lastBarTime2 && g_isSpreadOK && g_isTrendOK && g_buyProfit < g_pointMultiplier * 5 * g_pointValue + rates[0].close && 
           g_tradeMode == 1 && (int)(g_lastBarTime2 - g_lastBarTime) <= g_lastMarkedBarTime)  // 添加时间差检查
        {
            OpenBuy();
        }
        
        // 卖出条件
        if(CheckSellCondition(g_isSpreadOK, g_sellCount, g_highPrice, rates[0].close, VolatilityFactor, g_pointMultiplier, g_pointValue, trendStrength,
                             EntryFactor, rates[0].close, speedHigh, TimeCurrent(), g_sellCount, g_sellCount, g_sellCount, g_sellCount, g_expiryDate) &&
           g_lastBarTime2 != g_currentBarTime && g_isSpreadOK && g_isTrendOK && g_buyProfit > rates[0].close - g_pointMultiplier * 5 * g_pointValue && 
           g_tradeMode == 1 && (int)(g_lastBarTime2 - g_lastBarTime) <= g_lastMarkedBarTime)  // 添加时间差检查
        {
            OpenSell();
        }
        
        // 加仓买入条件
        if(CheckBuyAddCondition(g_isSpreadOK, g_buyCount, g_buyVolume, g_buyVolume, g_buyStopLoss, g_pointMultiplier, g_pointValue, rates[0].close,
                               g_highPrice, lowPrice, lowPrice, TimeCurrent(), g_buyCount, g_buyCount, g_buyCount, g_buyCount, g_expiryDate) &&
           g_lastBarTime != g_lastBarTime2 && TimeCurrent() - g_lastBarTime2 <= g_lastBarTime && g_isSpreadOK &&
           g_buyProfit < g_pointMultiplier * 5 * g_pointValue + rates[0].close && g_tradeMode == 1)
        {
            OpenBuy();
        }
        
        // 加仓卖出条件
        if(CheckSellAddCondition(g_isSpreadOK, g_sellCount, g_sellVolume, g_buyProfit, g_sellVolume, g_pointMultiplier, g_pointValue, rates[0].close,
                               g_highPrice, lowPrice, g_highPrice, TimeCurrent(), g_sellCount, g_sellCount, g_sellCount, g_sellCount, g_expiryDate) &&
           g_lastBarTime2 != g_currentBarTime && TimeCurrent() - g_lastBarTime2 <= g_lastBarTime && g_isSpreadOK &&
           g_buyProfit > rates[0].close - g_pointMultiplier * 5 * g_pointValue && g_tradeMode == 1)
        {
            OpenSell();
        }
    }
    
    // 检查平仓条件
    if(g_lastMarkedBarTime < (int)g_lastBarTime)  // 转换为整数进行比较
    {
        // 买入平仓条件
        if(CheckBuyCloseCondition(g_buyCount, rates[0].close, speedHigh, trendStrength, ExitFactor,
                                  TimeCurrent(), g_buyCount, g_buyCount, g_buyCount, g_buyCount, g_expiryDate))
        {
            CloseAllBuyOrders();
        }
        
        // 卖出平仓条件
        if(CheckSellCloseCondition(g_sellCount, rates[0].close, speedLow, trendStrength, ExitFactor,
                                    TimeCurrent(), g_sellCount, g_sellCount, g_sellCount, g_sellCount, g_expiryDate))
        {
            CloseAllSellOrders();
        }
        
        // 买入止盈条件
        if(CheckBuyTakeProfitCondition(g_buyCount, rates[0].close, g_buyVolume, ProfitFactor, g_pointMultiplier, g_pointValue,
                                       TimeCurrent(), g_buyCount, g_buyCount, g_buyCount, g_buyCount, g_expiryDate))
        {
            CloseAllBuyOrders();
        }
        
        // 卖出止盈条件
        if(CheckSellTakeProfitCondition(g_sellCount, rates[0].close, g_sellVolume, ProfitFactor, g_pointMultiplier, g_pointValue,
                                         TimeCurrent(), g_sellCount, g_sellCount, g_sellCount, g_sellCount, g_expiryDate))
        {
            CloseAllSellOrders();
        }
        
        // 买入二次止盈条件
        if(CheckBuySecondTakeProfitCondition(g_buyCount, g_buyProfit, trendStrength, ExitFactor2,
                                              TimeCurrent(), g_buyCount, g_buyCount, g_buyCount, g_buyCount, g_expiryDate))
        {
            CloseAllBuyOrders();
        }
        
        // 卖出二次止盈条件
        if(CheckSellSecondTakeProfitCondition(g_sellCount, g_sellProfit, trendStrength, ExitFactor2,
                                               TimeCurrent(), g_sellCount, g_sellCount, g_sellCount, g_sellCount, g_expiryDate))
        {
            CloseAllSellOrders();
        }
        
        g_lastMarkedBarTime = (int)g_lastBarTime;  // 转换为整数进行赋值
    }
    
    // 更新图表显示
    UpdateChartObjects();
    
    // 检查亚洲盘设置
    if(!EarlySession && StringFind(_Symbol, "GBPCAD", 0) >= 0)
    {
        Alert("请把亚盘开关打开");
        Sleep(100000);
    }
}

//+------------------------------------------------------------------+
//| 开仓买入订单                                                     |
//+------------------------------------------------------------------+
void OpenBuy()
{
    g_buyTicket = -1;
    g_buyCount = 0;
    g_buyVolume = 0;
    g_buyProfit = 0;
    g_buyOpenPrice = 0;
    g_buyStopLoss = 0;
    g_buyTakeProfit = 0;
    g_buyLastTime = g_lastBarTime2;
    
    // 计算止损止盈
    double highPrice = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, PRICE_HIGH, AdaptiveFactor, 2));
    double lowPrice = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, PRICE_LOW, AdaptiveFactor, 2));
    
    if(EarlySession)
    {
        g_buyStopLoss = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK) - StopLossPoints * g_pointMultiplier * g_pointValue, _Digits);
    }
    else
    {
        g_buyStopLoss = NormalizeDouble(lowPrice, _Digits);
    }
    
    // 计算仓位
    if(CompoundSwitch)
    {
        g_buyVolume = NormalizeDouble(AccountInfoDouble(ACCOUNT_EQUITY) * RiskPercent / 1000000, 2);
    }
    else
    {
        g_buyVolume = FixedLot;
    }
    
    if(SymbolInfoDouble(_Symbol, SYMBOL_ASK) - lowPrice > g_pointMultiplier * 110 * g_pointValue && DynamicSwitch && !EarlySession)
    {
        g_buyVolume *= 1.6;
    }
    
    g_buyVolume = MathMax(0.01, MathMin(50, g_buyVolume));
    
    if(g_buyTicket >= 0) return;
    
    while(g_buyCount < 3)
    {
        g_buyOpenPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        g_buyTakeProfit = NormalizeDouble(highPrice - lowPrice + (highPrice + lowPrice) / 2, _Digits);
        
        MqlTradeRequest request = {};
        MqlTradeResult result = {};
        
        request.action = TRADE_ACTION_DEAL;
        request.symbol = _Symbol;
        request.volume = g_buyVolume;
        request.type = ORDER_TYPE_BUY;
        request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        request.sl = g_buyStopLoss;
        request.tp = g_buyTakeProfit;
        request.deviation = g_slippage * g_pointMultiplier;
        request.magic = g_magicNumber;
        request.comment = EAComment;
        
        if(!OrderSend(request, result))
        {
            Print("下单错误 = ", GetLastError());
        }
        
        Sleep(1000);
        RefreshRates();
        g_buyCount++;
        
        if(g_buyTicket >= 0) return;
    }
}

//+------------------------------------------------------------------+
//| 开仓卖出订单                                                     |
//+------------------------------------------------------------------+
void OpenSell()
{
    g_sellTicket = -1;
    g_sellCount = 0;
    g_sellVolume = 0;
    g_sellProfit = 0;
    g_sellOpenPriceTotal = 0;
    g_sellStopLoss = 0;
    g_sellTakeProfit = 0;
    g_sellLastTime = g_currentBarTime;
    
    // 计算止损止盈
    double highPrice = iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, PRICE_HIGH, AdaptiveFactor, 2));
    double lowPrice = iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, PRICE_LOW, AdaptiveFactor, 2));
    
    if(EarlySession)
    {
        g_sellStopLoss = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID) + StopLossPoints * g_pointMultiplier * g_pointValue, _Digits);
    }
    else
    {
        g_sellStopLoss = NormalizeDouble(highPrice, _Digits);
    }
    
    // 计算仓位
    if(CompoundSwitch)
    {
        g_sellVolume = NormalizeDouble(AccountInfoDouble(ACCOUNT_EQUITY) * RiskPercent / 1000000, 2);
    }
    else
    {
        g_sellVolume = FixedLot;
    }
    
    if(highPrice - g_buyProfit > g_pointMultiplier * 110 * g_pointValue && DynamicSwitch && !EarlySession)
    {
        g_sellVolume *= 1.6;
    }
    
    g_sellVolume = MathMax(0.01, MathMin(50, g_sellVolume));
    
    if(g_sellTicket >= 0) return;
    
    while(g_sellCount < 3)
    {
        g_sellOpenPriceTotal += SymbolInfoDouble(_Symbol, SYMBOL_BID);
        g_sellTakeProfit = NormalizeDouble((highPrice + lowPrice) / 2 - (highPrice - lowPrice), _Digits);
        
        MqlTradeRequest request = {};
        MqlTradeResult result = {};
        
        request.action = TRADE_ACTION_DEAL;
        request.symbol = _Symbol;
        request.volume = g_sellVolume;
        request.type = ORDER_TYPE_SELL;
        request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        request.sl = g_sellStopLoss;
        request.tp = g_sellTakeProfit;
        request.deviation = g_slippage * g_pointMultiplier;
        request.magic = g_magicNumber;
        request.comment = EAComment;
        
        if(!OrderSend(request, result))
        {
            Print("下单错误 = ", GetLastError());
        }
        
        Sleep(1000);
        RefreshRates();
        g_sellCount++;
        
        if(g_sellTicket >= 0) return;
    }
}

//+------------------------------------------------------------------+
//| 统计持仓订单                                                     |
//+------------------------------------------------------------------+
void CountOrders()
{
    g_totalOrders = 0;
    g_pendingOrders = 0;
    g_buyCount = 0;
    g_sellCount = 0;
    g_buyVolume = 0;
    g_sellVolume = 0;
    g_buyProfit = 0;
    g_sellProfit = 0;
    g_buyVolumeTotal = 0;
    g_sellVolumeTotal = 0;
    g_buyProfitTotal = 0;
    g_sellProfitTotal = 0;
    g_buyLastVolume = 0;
    g_sellLastVolume = 0;
    g_buyLastProfit = 0;
    g_sellLastProfit = 0;
    g_buyOpenPriceTotal = 0;
    g_sellOpenPriceTotal = 0;
    g_buyLastTime = 0;
    g_sellLastTime = 0;
    
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
            if(PositionGetInteger(POSITION_MAGIC) != g_magicNumber) continue;
            
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
            {
                g_buyCount++;
                g_buyVolume += PositionGetDouble(POSITION_VOLUME);
                g_buyVolumeTotal += PositionGetDouble(POSITION_VOLUME);
                g_buyProfit += PositionGetDouble(POSITION_PROFIT);
                g_buyProfitTotal += PositionGetDouble(POSITION_PROFIT);
                g_buyOpenPriceTotal += PositionGetDouble(POSITION_PRICE_OPEN);
                g_buyLastVolume = PositionGetDouble(POSITION_VOLUME);
                g_buyLastProfit = PositionGetDouble(POSITION_PROFIT);
                g_buyLastTime = (datetime)PositionGetInteger(POSITION_TIME);
            }
            else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
            {
                g_sellCount++;
                g_sellVolume += PositionGetDouble(POSITION_VOLUME);
                g_sellVolumeTotal += PositionGetDouble(POSITION_VOLUME);
                g_sellProfit += PositionGetDouble(POSITION_PROFIT);
                g_sellProfitTotal += PositionGetDouble(POSITION_PROFIT);
                g_sellOpenPriceTotal += PositionGetDouble(POSITION_PRICE_OPEN);
                g_sellLastVolume = PositionGetDouble(POSITION_VOLUME);
                g_sellLastProfit = PositionGetDouble(POSITION_PROFIT);
                g_sellLastTime = (datetime)PositionGetInteger(POSITION_TIME);
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 关闭所有买单                                                     |
//+------------------------------------------------------------------+
void CloseAllBuyOrders()
{
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
            if(PositionGetInteger(POSITION_MAGIC) != g_magicNumber) continue;
            if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue;
            
            MqlTradeRequest request = {};
            MqlTradeResult result = {};
            
            request.action = TRADE_ACTION_DEAL;
            request.position = PositionGetTicket(i);
            request.symbol = _Symbol;
            request.volume = PositionGetDouble(POSITION_VOLUME);
            request.type = ORDER_TYPE_SELL;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            request.deviation = g_slippage * g_pointMultiplier;
            request.magic = g_magicNumber;
            request.comment = EAComment;
            
            if(!OrderSend(request, result))
            {
                Print("关闭买单失败. 错误: ", GetLastError());
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 关闭所有卖单                                                     |
//+------------------------------------------------------------------+
void CloseAllSellOrders()
{
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
            if(PositionGetInteger(POSITION_MAGIC) != g_magicNumber) continue;
            if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue;
            
            MqlTradeRequest request = {};
            MqlTradeResult result = {};
            
            request.action = TRADE_ACTION_DEAL;
            request.position = PositionGetTicket(i);
            request.symbol = _Symbol;
            request.volume = PositionGetDouble(POSITION_VOLUME);
            request.type = ORDER_TYPE_BUY;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            request.deviation = g_slippage * g_pointMultiplier;
            request.magic = g_magicNumber;
            request.comment = EAComment;
            
            if(!OrderSend(request, result))
            {
                Print("关闭卖单失败. 错误: ", GetLastError());
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 创建图表对象                                                     |
//+------------------------------------------------------------------+
void CreateChartObjects()
{
    // 创建EA运行状态标签
    ObjectCreate(0, "sd2", OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, "sd2", OBJPROP_TEXT, "EA运行状态：");
    ObjectSetInteger(0, "sd2", OBJPROP_FONTSIZE, 9);
    ObjectSetString(0, "sd2", OBJPROP_FONT, "Arial");
    ObjectSetInteger(0, "sd2", OBJPROP_COLOR, clrMagenta);
    ObjectSetInteger(0, "sd2", OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, "sd2", OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, "sd2", OBJPROP_YDISTANCE, 60);
    
    // 创建状态信息标签
    CreateStatusLabels();
}

//+------------------------------------------------------------------+
//| 创建状态信息标签                                                 |
//+------------------------------------------------------------------+
void CreateStatusLabels()
{
    // 多单信息标签
    CreateLabel("多亏1", "多单盈亏 : ", 80, DodgerBlue);
    CreateLabel("多数1", "多单手数 : ", 100, DodgerBlue);
    CreateLabel("多量1", "多单数量 : ", 120, DodgerBlue);
    
    // 分隔线
    CreateLabel("分界1", "------------------------", 140, OrangeRed);
    
    // 空单信息标签
    CreateLabel("空亏1", "空单盈亏 : ", 160, OrangeRed);
    CreateLabel("空数1", "空单手数 : ", 180, OrangeRed);
    CreateLabel("空量1", "空单数量 : ", 200, OrangeRed);
    
    // 多单数值标签
    CreateLabel("多亏2", "0.00", 80, DodgerBlue, 175);
    CreateLabel("多数2", "0.00", 100, DodgerBlue, 175);
    CreateLabel("多量2", "0", 120, DodgerBlue, 175);
    
    // 空单数值标签
    CreateLabel("空亏2", "0.00", 160, OrangeRed, 175);
    CreateLabel("空数2", "0.00", 180, OrangeRed, 175);
    CreateLabel("空量2", "0", 200, OrangeRed, 175);
}

//+------------------------------------------------------------------+
//| 创建单个标签                                                     |
//+------------------------------------------------------------------+
void CreateLabel(string name, string text, int yDistance, color textColor, int xDistance = 105)
{
    ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, name, OBJPROP_TEXT, text);
    ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9);
    ObjectSetString(0, name, OBJPROP_FONT, "Arial");
    ObjectSetInteger(0, name, OBJPROP_COLOR, textColor);
    ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, name, OBJPROP_XDISTANCE, xDistance);
    ObjectSetInteger(0, name, OBJPROP_YDISTANCE, yDistance);
}

//+------------------------------------------------------------------+
//| 更新图表对象                                                     |
//+------------------------------------------------------------------+
void UpdateChartObjects()
{
    // 更新EA运行状态
    string status = g_isSpreadOK ? "-----运行正常-----" : "↓ ---运行失败，有以下原因--- ↓";
    color statusColor = g_isSpreadOK ? clrLime : clrYellow;
    int fontSize = g_isSpreadOK ? 10 : 9;
    
    ObjectCreate(0, "sd3", OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, "sd3", OBJPROP_TEXT, status);
    ObjectSetInteger(0, "sd3", OBJPROP_FONTSIZE, fontSize);
    ObjectSetString(0, "sd3", OBJPROP_FONT, "Arial");
    ObjectSetInteger(0, "sd3", OBJPROP_COLOR, statusColor);
    ObjectSetInteger(0, "sd3", OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, "sd3", OBJPROP_XDISTANCE, 105);
    ObjectSetInteger(0, "sd3", OBJPROP_YDISTANCE, 60);
    
    if(!g_isSpreadOK)
    {
        // 删除所有交易信息标签
        DeleteTradeInfoLabels();
    }
    else
    {
        // 更新交易信息
        UpdateTradeInfoLabels();
    }
}

//+------------------------------------------------------------------+
//| 删除交易信息标签                                                 |
//+------------------------------------------------------------------+
void DeleteTradeInfoLabels()
{
    string labels[] = {
        "多亏1", "多数1", "多量1", "分界1", "空亏1", "空数1", "空量1",
        "多亏2", "多数2", "多量2", "空亏2", "空数2", "空量2"
    };
    
    for(int i = 0; i < ArraySize(labels); i++)
    {
        ObjectDelete(0, labels[i]);
    }
}

//+------------------------------------------------------------------+
//| 更新交易信息标签                                                 |
//+------------------------------------------------------------------+
void UpdateTradeInfoLabels()
{
    // 更新多单信息
    ObjectSetString(0, "多亏2", OBJPROP_TEXT, DoubleToString(g_sellProfit, 2));
    ObjectSetString(0, "多数2", OBJPROP_TEXT, DoubleToString(g_sellVolume, 2));
    ObjectSetString(0, "多量2", OBJPROP_TEXT, IntegerToString(g_sellCount));
    
    // 更新空单信息
    ObjectSetString(0, "空亏2", OBJPROP_TEXT, DoubleToString(g_buyProfit, 2));
    ObjectSetString(0, "空数2", OBJPROP_TEXT, DoubleToString(g_buyVolume, 2));
    ObjectSetString(0, "空量2", OBJPROP_TEXT, IntegerToString(g_buyCount));
}

//+------------------------------------------------------------------+
//| 显示图表消息                                                     |
//+------------------------------------------------------------------+
void ShowMessage(string message, bool isError = false)
{
    ObjectCreate(0, "Message", OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, "Message", OBJPROP_TEXT, message);
    ObjectSetInteger(0, "Message", OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, "Message", OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, "Message", OBJPROP_YDISTANCE, 40);
    ObjectSetInteger(0, "Message", OBJPROP_COLOR, isError ? clrRed : clrYellow);
}

//+------------------------------------------------------------------+
//| 超能系列函数 - 交易信号生成器                                    |
//+------------------------------------------------------------------+

// 超能1函数 - 计算趋势强度
double CalculateTrendStrength(double high, double close, double open, double low)
{
    return (high - close) * (-100.0) / (open - low);
}

// 超能2函数 - 检查买入条件
bool CheckBuyCondition(bool spreadOK, int buyCount, double close, double low, int volatilityFactor, 
                      int pointMultiplier, double point, double trendStrength, int entryFactor,
                      double currentPrice, double highPrice, int currentTime, int param1, int param2,
                      int param3, int param4, double param5)
{
    if(!spreadOK || buyCount >= 1) return false;
    if((pointMultiplier * volatilityFactor) * point >= close - low) return false;
    if((entryFactor - 100) < trendStrength) return false;
    if(highPrice <= currentPrice) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能3函数 - 检查卖出条件
bool CheckSellCondition(bool spreadOK, int sellCount, double high, double close, int volatilityFactor,
                       int pointMultiplier, double point, double trendStrength, int entryFactor,
                       double currentPrice, double lowPrice, int currentTime, int param1, int param2,
                       int param3, int param4, double param5)
{
    if(!spreadOK || sellCount >= 1) return false;
    if((pointMultiplier * volatilityFactor) * point >= high - close) return false;
    if(-entryFactor > trendStrength) return false;
    if(lowPrice >= currentPrice) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能4函数 - 检查买入加仓条件
bool CheckBuyAddCondition(bool spreadOK, int buyCount, double buyPrice, double currentPrice, double stopLoss,
                         int pointMultiplier, double point, double trendStrength, double high, double low,
                         double lowest, int currentTime, int param1, int param2, int param3, int param4,
                         double param5)
{
    if(!spreadOK || buyCount >= 5) return false;
    if(buyPrice <= 0.0) return false;
    if((3 * pointMultiplier) * point >= currentPrice - stopLoss) return false;
    if(0.5 * ((high + low) * 0.5 + lowest) >= trendStrength) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能5函数 - 检查卖出加仓条件
bool CheckSellAddCondition(bool spreadOK, int sellCount, double sellPrice, double currentPrice, double stopLoss,
                          int pointMultiplier, double point, double trendStrength, double high, double low,
                          double highest, int currentTime, int param1, int param2, int param3, int param4,
                          double param5)
{
    if(!spreadOK || sellCount >= 5) return false;
    if(sellPrice <= 0.0) return false;
    if((3 * pointMultiplier) * point >= currentPrice - stopLoss) return false;
    if(0.5 * ((high + low) * 0.5 + highest) <= trendStrength) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能6函数 - 检查买入平仓条件
bool CheckBuyCloseCondition(int buyCount, double currentPrice, double highPrice, double trendStrength,
                           int exitFactor, int currentTime, int param1, int param2, int param3, int param4,
                           double param5)
{
    if(buyCount <= 0) return false;
    if(highPrice >= currentPrice) return false;
    if(-exitFactor > trendStrength) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能7函数 - 检查卖出平仓条件
bool CheckSellCloseCondition(int sellCount, double currentPrice, double lowPrice, double trendStrength,
                            int exitFactor, int currentTime, int param1, int param2, int param3, int param4,
                            double param5)
{
    if(sellCount <= 0) return false;
    if(lowPrice <= currentPrice) return false;
    if((exitFactor - 100) < trendStrength) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能8函数 - 检查买入止盈条件
bool CheckBuyTakeProfitCondition(int buyCount, double currentPrice, double buyPrice, int profitFactor,
                                int pointMultiplier, double point, int currentTime, int param1, int param2,
                                int param3, int param4, double param5)
{
    if(buyCount <= 0) return false;
    if((pointMultiplier * profitFactor) * point + buyPrice >= currentPrice) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能9函数 - 检查卖出止盈条件
bool CheckSellTakeProfitCondition(int sellCount, double currentPrice, double sellPrice, int profitFactor,
                                 int pointMultiplier, double point, int currentTime, int param1, int param2,
                                 int param3, int param4, double param5)
{
    if(sellCount <= 0) return false;
    if(sellPrice - (pointMultiplier * profitFactor) * point <= currentPrice) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能10函数 - 检查买入二次止盈条件
bool CheckBuySecondTakeProfitCondition(int buyCount, double buyProfit, double trendStrength, int exitFactor2,
                                      int currentTime, int param1, int param2, int param3, int param4, double param5)
{
    if(buyCount <= 0) return false;
    if(buyProfit <= 0.0) return false;
    if(-exitFactor2 > trendStrength) return false;
    if(currentTime > param5) return false;
    
    return true;
}

// 超能11函数 - 检查卖出二次止盈条件
bool CheckSellSecondTakeProfitCondition(int sellCount, double sellProfit, double trendStrength, int exitFactor2,
                                       int currentTime, int param1, int param2, int param3, int param4, double param5)
{
    if(sellCount <= 0) return false;
    if(sellProfit <= 0.0) return false;
    if((exitFactor2 - 100) < trendStrength) return false;
    if(currentTime > param5) return false;
    
    return true;
}

//+------------------------------------------------------------------+
//| 检查是否允许交易                                                 |
//+------------------------------------------------------------------+
bool IsTradeAllowed()
{
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        g_isSpreadOK = false;
        return false;
    }
    
    if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
    {
        g_isSpreadOK = false;
        return false;
    }
    
    if(!AccountInfoInteger(ACCOUNT_TRADE_EXPERT))
    {
        g_isSpreadOK = false;
        return false;
    }
    
    if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
    {
        g_isSpreadOK = false;
        return false;
    }
    
    g_isSpreadOK = true;
    return true;
} 